package mil.af.amc.adpetracker.service;

import mil.af.amc.adpetracker.exceptions.DateFormatException;
import mil.af.amc.adpetracker.exceptions.EquipmentItemNotFoundException;
import mil.af.amc.adpetracker.model.EquipmentItem;
import mil.af.amc.adpetracker.service.exceptions.AdpeAccountNotFoundException;
import mil.af.amc.adpetracker.service.exceptions.ItemStatusNotFoundException;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Interface for the Equipment Item Service
 *
 * @author TSgt Jason Ferguson
 */

public interface EquipmentItemService {

    /**
     * Create a single equipment item
     *
     * @param item
     * @return
     */
    EquipmentItem createItem(EquipmentItem item);

    EquipmentItem getBySerialNumber(String serial);

    EquipmentItem getBySerialAndManufacturer(String serial, int manufacturerId);

    EquipmentItem getById(int id);

    void delete(EquipmentItem item);

    void save(EquipmentItem item);

    /**
     * Creates and saves a List of EquipmentItem objects based in input from a Map (usually a
     * Struts form or DynaActionForm)
     *
     * @param itemMap   Map containing information for the items
     */
    void saveItems(Map itemMap);

    /**
     * Create several equipment items based on form information, including an uploaded
     * file in a set format
     *
     * @param itemInfo
     * @return
     */
    List<EquipmentItem> createMultipleItems(Map itemInfo);

    List<EquipmentItem> createMultipleItems(byte[] file)
            throws AdpeAccountNotFoundException, ItemStatusNotFoundException, DateFormatException;

    void editItem(Map itemMap) throws EquipmentItemNotFoundException, DateFormatException;

    int getCountByAccount(int accountId);

    List<EquipmentItem> getAll();

    /**
     * Retrieve a list of Equipment Items object based on the unique id of the item's model
     *
     * @param itemModelId   an int representing the unique id of the item model
     * @return      a List of EquipmentItem objects
     */
    List<EquipmentItem> getAllByItemModel(int itemModelId);

    List<EquipmentItem> getAllByAccount(int accountId);

    List<EquipmentItem> getAllActiveByAccount(int accountId);

    /**
     * Get all CURRENT (non DRMO, no ROS) items by the given account
     *
     * @param accountId
     * @return
     */
    List<EquipmentItem> getAllCurrentByAccount(int accountId);

    /**
     * Assign an item to a user. A HashMap<String, Object> is returned for testing purposes.
     *
     * @param itemMap   a Map representing an object being assigned to a user
     */
    void assignItem(Map itemMap) throws ServiceException;

    /**
     * Unassign an item from a user
     *
     * @param itemId    int representing unique id of the item to unassign
     * @throws ServiceException
     */
    void unassignItem(int itemId) throws ServiceException;

    /**
     * Get a list of items by the item type
     *
     * @param equipmentTypeId   int representing the unique id of the equipment type
     * @return  a List containing the EquipmentItems of that type
     */
    List<EquipmentItem> getByItemType(int equipmentTypeId);

    /**
     * Get a list of items (you figure out what this means!)
     *
     * @param adpeAccountId
     * @param equipmentTypeId
     * @param manufacturerId
     * @return
     * @throws ServiceException
     */
    List<EquipmentItem> getByAdpeAccountAndEquipmentTypeAndManufacturer(int adpeAccountId,
                                                                        int equipmentTypeId,
                                                                        int manufacturerId);

    /**
     * Get a list of items by manufacturer
     *
     * @param manufacturerId
     * @return
     */
    List<EquipmentItem> getByManufacturer(int manufacturerId);

    /**
     * Send a status email to a User to remind them of any items they have assigned
     *
     * @param userId    an int representing the unique id of the user
     */
    void sendStatusEmail(int userId) throws ServiceException;

    void updateLocation(EquipmentItem item, String location);

    void updateInventoryDate(int itemId, Date date);

    /**
     * Transfer an item to a different ADPE Account
     *
     * @param serialNumber
     * @param accountId
     * @throws ServiceException
     */
    public void transferItem(String serialNumber, int accountId) throws ServiceException;

    /**
     * Transfer one or more items to a new ADPE account
     * 
     * @param pkgItemId
     * @param accountId
     * @throws ServiceException
     */
    public void transferItems(Integer[] pkgItemId, int accountId) throws ServiceException;
}
